package biblio;

import java.io.Serializable;
import java.util.Collection;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Observable;

/**
 * Classe de gestion d'ouvrage.
 * @author IUT, refactor� par E. Ceret
 * @version 2.0
 */
public class Ouvrage extends Observable implements Serializable {

	// ************************************************************************************************************
	// Constantes
	// ************************************************************************************************************

	private static final long serialVersionUID = 1L;
	
	// ************************************************************************************************************
	// Attributs
	// ************************************************************************************************************

	private String _isbn;
	private String _titre;
	private String _editeur;
	private GregorianCalendar _dateEdition;
	private int _derNumExemplaire;
	private int _derNbAuteur;

	// Attributs d'Association
	private HashMap<Integer, Exemplaire> _exemplaires;
	private HashMap<Integer, Auteur> _tesAuteurs;
	
	// ************************************************************************************************************
	// Constructeur
	// ************************************************************************************************************

	/**
	 * Constructeur. 
	 * @param isbn			numero ISBN de l'ouvrage
	 * @param titre			titre de l'ouvrage
	 * @param auteur		auteur de l'ouvrage
	 * @param editeur		editeur de l'ouvrage
	 * @param dateEdition	date d'edition
	 */
	public Ouvrage(String isbn, String titre, String editeur, GregorianCalendar dateEdition) {
		
		this.setIsbn(isbn);
		this.setTitre(titre);
		this.setAuteur(new HashMap<Integer, Auteur>());
		this.setDerNbAuteur(0);
		this.setEditeur(editeur);
		this.setDateEdition(dateEdition);
		this.setExemplaires(new HashMap<Integer, Exemplaire>());
		this.setDerNumExemplaire(0);
		

				
	} // Fin Constructeur

	// ************************************************************************************************************
	// M�thodes priv�es
	// ************************************************************************************************************
	
	// ------------------------------------------------------------------------------------------------------------
	// Affecteurs
	
	/**
	 * setter de l'attribut auteur
	 * @param auteur valeur � affecter � l'auteur de l'ouvrage
	 */
	public void setAuteur(HashMap<Integer, Auteur> auteur){
		_tesAuteurs = auteur;
	}
	
	/**
	 * setter de l'attribut dateEdition
	 * @param date valeur � affecter � la date d'�dition de l'ouvrage
	 */
	private void setDateEdition(GregorianCalendar date){
		_dateEdition = date;
	}
	
	/**
	 * setter de l'attribut editeur
	 * @param editeur valeur � affecter � l'�diteur de l'ouvrage
	 */
	private void setEditeur(String editeur){
		_editeur = editeur;
	}

	/**
	 * setter de l'attrribut exemplaires (ensemble des exemplaires de l'ouvrage)
	 * @param exemplaires hashmap d'exemplaires
	 */
	public void setExemplaires(HashMap<Integer, Exemplaire> exemplaires) {
		_exemplaires = exemplaires;
	}
	
	/**
	 * setter de l'attribut n� d'ISBN.
	 * @param isbn valeur � affecter � l'ISBN de l'ouvrage
	 */
	private void setIsbn(String isbn) {
		this._isbn = isbn;
	}

	/**
	 * setter de l'attribut titre.
	 * @param titre valeur � affecter au titre de l'ouvrage
	 */
	private void setTitre(String titre){
		_titre = titre;
	}
	
	/**
	 * setter du n� du dernier exemplaire.
	 * @param derNumExemplaire nombre � affecter au dernier num�ro d'exemplaire
	 */
	private void setDerNumExemplaire(int derNumExemplaire) {
		_derNumExemplaire  = derNumExemplaire ;
	}
	
	/**
	 * setter du n� du dernier auteur.
	 * @param derNumExemplaire nombre � affecter au dernier num�ro d'exemplaire
	 */
	private void setDerNbAuteur(int derNbAuteur) {
		_derNbAuteur  = derNbAuteur;
	}
	
	/**
	 * getter du dernier num�ro d'exemplaire
	 * @return un entier repr�sentant le dernier num�ro d'exemplaire de l'ouvrage
	 */
	private int getDerNumExemplaire() {
		return _derNumExemplaire;
	}
	
	/**
	 * getter du dernier num�ro de l'auteur
	 * @return un entier repr�sentant le dernier num�ro de l'auteur de l'ouvrage
	 */
	private int getDerNbAuteur() {
		return _derNbAuteur;
	}
	
	// ------------------------------------------------------------------------------------------------------------
	// Traitements

	/**
	 * Lie un exemplaire � l'ouvrage. Ins�re un exemplaire dans l'ensemble des exemplaires de l'ouvrage, avec son numero.
	 * @param numero numero de l'exemplaire � ins�rer
	 * @param exemplaire exemplaire � ins�rer
	 */
	private void lierExemplaire(int numero, Exemplaire exemplaire) {
		_exemplaires.put(numero, exemplaire);
	} // Fin lierExemplaire

	
	/**
	 * G�n�re un num�ro d'exemplaire.
	 * @return un entier repr�sentant le prochain num�ro disponible pour un exemplaire de l'ouvrage 
	 */
	private int genererNumeroExemplaire() {
		this.setDerNumExemplaire(this.getDerNumExemplaire() + 1);
		return this.getDerNumExemplaire();
	} // Fin genererNumeroExemplaire

	/**
	 * G�n�re un num�ro de l'auteur.
	 * @return un entier repr�sentant le prochain num�ro disponible pour un auteur de l'ouvrage 
	 */
	private int genererNumeroAuteur() {
		this.setDerNbAuteur(this.getDerNbAuteur() + 1);
		return this.getDerNbAuteur();
	} // Fin genererNumeroAuteur


	/**
	 * @param ouvrage l'ouvrage � lier � l'auteur
	 */
	private void lierAuteur(int numero, Auteur auteurs) {
		_tesAuteurs.put(numero, auteurs);
	} // Fin lierAuteur

	// ************************************************************************************************************
	// M�thodes publiques
	// ************************************************************************************************************

	// ------------------------------------------------------------------------------------------------------------
	// Accesseurs
	
	/**
	 * Getter de l'ISBN.
	 * @return ISBN de l'ouvrage
	 */
	public String getIsbn() {
		return _isbn;
	}

	/**
	 * Getter du titre.
	 * @return titre de l'ouvrage
	 */
	public String getTitre() {
		return _titre;
	}

	
//	*********************************** AUTEURS *******************
	/**
	 * getter de l'auteur.
	 * @return auteur de l'ouvrage
	 */
	public Auteur getAuteur(int numero) {
		return (Auteur)_tesAuteurs.get(numero);
	} // Fin unAuteur
	
	/**
	 * getter de l'ensemble des auteurs.
	 * @return une collection d'auteurs
	 */
	public Collection<Auteur> getAuteurs() {
		return _tesAuteurs.values();
	}
	
	/**
	 * getter du nombre d'exemplaires de l'ouvrage.
	 * @return un entier repr�sentant le nombre d'auteurs
	 */
	public int getNbAuteurs() {
		return _tesAuteurs.size();
	}
	
//	*************************************************************

	

	/**
	 * getter de l'editeur.
	 * @return editeur de l'ouvrage
	 */
	public String getEditeur() {
		return _editeur;
	}

	/**
	 * getter de dateEdition.
	 * @return date d'�dition de l'ouvrage
	 */
	public GregorianCalendar getDateEdition() {
		return _dateEdition;
	}

	/**
	 * getter d'un exemplaire de l'ouvrage.
	 * @param numero numero de l'exemplaire retourn�
	 * @return l'exemplaire dont le num�ro a �t� pass� en param�tre, s'il existe
	 */
	public Exemplaire getExemplaire(int numero) {
		return (Exemplaire) _exemplaires.get(numero);
	} // Fin unExemplaire

	/**
	 * getter de l'ensemble des exemplaires.
	 * @return une collection d'exemplaires
	 */
	public Collection<Exemplaire> getExemplaires() {
		return _exemplaires.values();
	}
	
	/**
	 * getter du nombre d'exemplaires de l'ouvrage.
	 * @return un entier repr�sentant le nombre d'exemplaires
	 */
	public int getNbExemplaires() {
		return _exemplaires.size();
	}
	

	// ------------------------------------------------------------------------------------------------------------
	// Traitements

	/**
	 * Ajout d'un exemplaire � l'ouvrage. Le num�ro de cet exemplaire est g�n�r� automatiquement pour l'ouvrage.
	 * @param dateReception date � laquelle l'exemplaire a �t� re�u.
	 */
	public void ajouterExemplaire(GregorianCalendar dateReception) {
		// Generation du numero chronologique de l'exemplaire
		int numero = this.genererNumeroExemplaire();
		
		// Creation de l'exemplaire
		Exemplaire exemplaire = new Exemplaire(numero, dateReception, this);
		
		// liaison de l'ouvrage a l'exemplaire
		this.lierExemplaire(numero, exemplaire);
		
	} // Fin ajouterExemplaire
	
	/**
	 * Ajout d'un auteur � l'ouvrage. Le num�ro de cet auteur est g�n�r� automatiquement pour l'ouvrage.
	 * @param @param nomAuteur			nom de l'auteur
	 * @param prenomAuteur			prénom de l'auteure�u.
	 */
	public void ajouterAuteur(String nomAuteur, String prenomAuteur) {
		// Generation du numero chronologique de l'exemplaire
		int numero = this.genererNumeroAuteur();
		
		// Creation de l'exemplaire
		Auteur auteur = new Auteur(nomAuteur, prenomAuteur);
		
		// liaison de l'ouvrage a l'exemplaire
		this.lierAuteur(numero, auteur);
		
	} // Fin ajouterExemplaire

	/**
	 * @param dateRecep
	 * @return
	 */
	public boolean verifDate(GregorianCalendar dateRecep) {
		return (dateRecep.after(_dateEdition));
	}

} // Fin Classe Ouvrage
